# 计算L2误差
import numpy as np

def calculate_L2_Error(
    uh: np.ndarray,
    u_real: np.ndarray,
    *,
    Nx: int,
    NumGLP: int,
    dimPk: int,
    phiG: np.ndarray,     # (NumGLP, dimPk)
    weight: np.ndarray,   # (NumGLP,)
    hx1: float
) -> float:
    """
    计算 L2 误差

    参数
    ----
    uh : (Nx, dimPk) 数值解系数
    u_real : (Nx, NumGLP) 真实解在高斯点上的值（或同形状的矩阵）
    Nx : 单元个数
    NumGLP : 每单元高斯积分点数
    dimPk : 每单元基函数数目
    phiG : (NumGLP, dimPk) 高斯点上的基函数值
    weight : (NumGLP,) 高斯权重
    hx1 : 单元宽度

    返回
    ----
    L2_Error : float L2 误差
    """

    # Step 1: 在高斯点上重构数值解 uhG
    uhG = np.zeros((Nx, NumGLP))
    for i in range(Nx):
        for d in range(dimPk):
            uhG[i, :] += uh[i, d] * phiG[:, d]

    # Step 2: 计算误差
    uE = np.abs(uhG - u_real)

    # Step 3: 积分求 L2 误差
    L2_Error = 0.0
    for i in range(Nx):
        for i1 in range(NumGLP):
            L2_Error += hx1 * weight[i1] * (uE[i, i1] ** 2)

    L2_Error = np.sqrt(L2_Error)
    return L2_Error